import { series } from 'gulp'
import fs from 'fs-extra'
import path from 'path'
import chalk from 'chalk'
import { rollup } from 'rollup'
import rollupConfig from './rollup.config'
import conventionalChangelog from 'conventional-changelog'
import {
  Extractor,
  ExtractorConfig,
  ExtractorResult,
} from '@microsoft/api-extractor'

interface TaskFunc {
  (cb: Function): void
}

const log = {
  progress: (text: string) => {
    console.log(chalk.green(text))
  },
  error: (text: string) => {
    console.log(chalk.red(text))
  },
}

const paths = {
  root: path.join(__dirname, '/'),
  lib: path.join(__dirname, '/lib'),
}



// 删除 lib 文件
const clearLibFile: TaskFunc = async (cb) => {
  fs.removeSync(paths.lib)
  log.progress('Deleted lib file')
  cb()
}

// rollup 打包
const buildRollup: TaskFunc = async (cb) => {
  const inputOptions = {
    input: rollupConfig.input,
    external: rollupConfig.external,
    plugins: rollupConfig.plugins,
  }
  const outOptions = rollupConfig.output
  const bundle = await rollup(inputOptions)
  // console.log('bundle', bundle)
  if(Array.isArray(outOptions)) {
    outOptions.forEach(async (option: any) => {
      await bundle.write(option)
    })
    cb()
    log.progress('Rollup built successfully')
  }
}

// 使用 @microsoft/api-extractor 这个库是为了把所有的 .d.ts 合成一个
const apiExtractorGenerate:TaskFunc = async (cb) => {
  const apiExtractorJsonPath: string = path.join(__dirname, './/api-extractor.json')
  // 加载并解析 api-extractor.json 文件
  // ExtractorConfig.loadFileAndPrepare: loads the api-extractor.json config file from the specified file path, and prepares an ExtractorConfig object.
  const extractorConfig: ExtractorConfig = await ExtractorConfig.loadFileAndPrepare(apiExtractorJsonPath)
  // console.log('extractorConfig', extractorConfig)
  const isExist: boolean = await fs.pathExists(extractorConfig.mainEntryPointFilePath)
  if (!isExist) {
    log.error('API Extractor not find index.d.ts')
    return
  }
  const extractorResult: ExtractorResult = await Extractor.invoke(extractorConfig, {
    localBuild: true,
    // 在输出中显示信息
    showVerboseMessages: true,
  })
  // console.log('extractorResult', extractorResult)
  if(extractorResult.succeeded) {
    // 删除多余的 .d.ts 文件 
    const libFiles: string[] = await fs.readdir(paths.lib)
    libFiles.forEach(async file => {
      // 除index.d.ts以外的文件
      if(file.endsWith('.d.ts') && !file.includes('index')) {
        await fs.remove(path.join(paths.lib, file))
      }
    })
    log.progress('API Extractor completed successfully')
    cb()
  } else {
    log.error(`API Extractor completed with ${extractorResult.errorCount} errors`
    + ` and ${extractorResult.warningCount} warnings`)
  }
}

// 完成
const complete: TaskFunc = (cb) => {
  cb()
}

// 构建过程
// 1. 删除 lib 文件夹
// 2. rollup 打包
// 3. api-extractor 生成统一的声明文件, 删除多余的声明文件
// 4. 完成
export const build = series(clearLibFile, buildRollup,apiExtractorGenerate, complete)


export const changelog:TaskFunc = async (cb)=> {
  const changelogPath: string = path.join(paths.root, 'CHANGELOG.md')
  const changelogPipe = await conventionalChangelog({
    preset: 'angular',
    releaseCount: 0,
  })
  changelogPipe.setEncoding('utf-8')
  // console.log('changelogPipe',changelogPipe)
  const resultArry = ['# 工具库更新日志\n\n']
  changelogPipe.on('data', (chunk)=>{
    // console.log('chunk', chunk)
    chunk = chunk.replace(/\/commits\//g, '/commit/')
    resultArry.push(chunk)
    // console.log('resultArry', resultArry)
  })
  changelogPipe.on('end', async ()=>{
    await fs.createWriteStream(changelogPath).write(resultArry.join(''))
    cb()
  })
}